package com.article_main.service;

import com.account_api.UserApi;
import com.article_main.mapper.ArticleMapper;
import com.article_main.search.ArticleSearchRepository;
import com.article_main.search.ArticleSearchRepositoryImpl;
import com.article_main.search.IArticleSearchRepository;
import com.article_protocol.pojo.dto.AddArticleDTO;
import com.article_protocol.pojo.dto.GetArticleDTO;
import com.article_protocol.pojo.entity.Article;
import com.article_protocol.pojo.po.AddArticlePO;
import com.article_protocol.pojo.po.ArticleSearchPO;
import com.article_protocol.pojo.po.GetUserArticlePO;
import com.common.ex.myException.FileUploadException;
import com.common.pojo.MyUserDetails;
import com.common.result.JsonResult;
import com.common.result.ResultEnum;
import com.common.utils.FileUploadUtils;
import com.common.utils.SnowflakeIdGenerator;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class ArticleServiceImpl implements IArticleService{
    @Autowired
    private ArticleMapper articleMapper;
//    @Value("${config.article_path}")
    @Autowired
    private IArticleSearchRepository articleSearchRepositoryImpl;
    private String ARTICLE_PATH="";
    @Value("${config.base_path}")
    private  String BASE_PATH;
    @DubboReference
    private UserApi userService;

    private SnowflakeIdGenerator idGenerator;
    public void test(){
        log.info("ArticleService测试dubbo");
        userService.sayHello();
    }

    public ArticleServiceImpl(){
        idGenerator = new SnowflakeIdGenerator(1L, 1L);
        log.info("创建雪花实例");
    }

    @Transactional
    public JsonResult addArticle(MultipartFile multipartFile, SecurityContextHolder securityContextHolder) {
        AddArticlePO addArticlePO=new AddArticlePO();

//        Object data = addArticleDTO.getData();
//        if (data instanceof MultipartFile){
//            MultipartFile multipartFile = (MultipartFile) data;
//            try {
//                int upload = FileUploadUtils.upload(multipartFile);
//            } catch (IOException e) {
//                log.warn("文件格式出错，传到后端的并不是一个multipartFile类型");
//                throw new FileUploadException();
//            }
        Authentication authentication=securityContextHolder.getContext().getAuthentication();
        //setUId
        if (authentication != null && authentication.isAuthenticated()) {
            Object userDetails = authentication.getPrincipal();
            if (userDetails instanceof MyUserDetails){
                MyUserDetails myUserDetails = (MyUserDetails) userDetails;
                addArticlePO.setUid(myUserDetails.getUid());
            }

        }
        addArticlePO.setCreateTime(LocalDateTime.now());

        SnowflakeIdGenerator snowflakeIdGenerator=new SnowflakeIdGenerator(1L,1L);
        long articleId = snowflakeIdGenerator.nextId();
        addArticlePO.setArticleId(articleId);
        int constResult =articleMapper.addArticle(addArticlePO);
        return uploadFile(multipartFile, ARTICLE_PATH);

    }

//            log.info("service:sql插入返回值：${}"+constResult);
//            if (constResult==1){
//                return JsonResult.ok();
//            }else {
//                return  new JsonResult(ResultEnum.ADD_ARTICLE_FAILED);
//            }

//        }else {
//            return new JsonResult(ResultEnum.FILE_UPLOAD_FAILED);
//        }
    public String getArticleContent(String path){
        log.info("service层打印查询用户文章path:{}",path);

        Path sourcePath= Paths.get(path);
        List<String> lines = null;
        try {
            lines = Files.readAllLines(sourcePath, StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String content = String.join("\n", lines); // 合并成完整字符串
        return  content;
    }
    public JsonResult getArticle(long aid){
        GetUserArticlePO getUserArticlePO = articleMapper.getArticle(aid);
        if (getUserArticlePO!=null){
            GetArticleDTO getArticleDTO = new GetArticleDTO();
            String location=getUserArticlePO.getLocation();
            BeanUtils.copyProperties(getUserArticlePO,getArticleDTO);
            String articleContent = getArticleContent(location);
            getArticleDTO.setData(articleContent);
            log.info("articleService打印文章长度:{}",articleContent.length());
            if (articleContent.length()>=100){
                StringBuilder stringBuilder=new StringBuilder(articleContent);
                String substring = stringBuilder.substring(0, 100);
                getArticleDTO.setSynopsis(substring);
            }else {
                getArticleDTO.setSynopsis(articleContent);
            }

            return JsonResult.ok(getArticleDTO);
        }
        else {
            return new JsonResult(ResultEnum.GET_ARTICLE_NOT_EXIST);
        }
    }

    public List<GetArticleDTO> getIndexArticle(@NotNull @RequestParam int pageNum){
        PageHelper.startPage(pageNum,10);
        List<GetUserArticlePO> getUserArticlePOS = articleMapper.getIndexArticle(pageNum);
        log.info("ArticleService打印getUserArticlePOS:{}",getUserArticlePOS);


        List<GetArticleDTO> getArticleDTOS = new ArrayList<>();

        for (GetUserArticlePO getUserArticlePO : getUserArticlePOS ){
            if (getUserArticlePO!=null){
                String location=getUserArticlePO.getLocation();
                String articleData = getArticleContent(location);
                log.info("service层打印查询用户文章location:{}",location);
                GetArticleDTO getArticleDTO = new GetArticleDTO();
                getArticleDTO.setData(articleData);
                BeanUtils.copyProperties(getUserArticlePO,getArticleDTO);
                log.info("ArticleService打印加入articleS的article:{}",getArticleDTO);
               //加入synopsis简介
                if (articleData.length()>=100){
                    StringBuilder stringBuilder=new StringBuilder(articleData);
                    String substring = stringBuilder.substring(0, 100);
                    getArticleDTO.setSynopsis(substring);
                }else {
                    getArticleDTO.setSynopsis(articleData);
                }
                getArticleDTOS.add(getArticleDTO);
            }
        }
        return getArticleDTOS;
    }


    public JsonResult uploadPicture(MultipartFile multipartFile) throws IOException {
        FileUploadUtils fileUploadUtils=new FileUploadUtils();
        int resultCode = fileUploadUtils.uoloadPicture(multipartFile);
        if (resultCode==0){
            return JsonResult.ok();
        }
        else {
            return new JsonResult(ResultEnum.FILE_UPLOAD_FAILED);
        }
    }

    public JsonResult uploadFile(MultipartFile multipartFile, String path){
        FileUploadUtils fileUploadUtils=new FileUploadUtils();
        try {

            int uploadResult = fileUploadUtils.upload(multipartFile, path);
            if (uploadResult==3){
                return new JsonResult(ResultEnum.FILE_NOT_ALLOWED_EMPTY);
            }
        } catch (IOException e) {
            log.warn("文件格式出错，传到后端的并不是一个multipartFile类型");
            throw new FileUploadException();
        }
        return JsonResult.ok();
    }


    public JsonResult getUserArticle(int pageNum,SecurityContextHolder securityContextHolder){
        Authentication authentication = securityContextHolder.getContext().getAuthentication();
        MyUserDetails details = (MyUserDetails)authentication.getPrincipal();
        log.info(details+"");
        long uid = details.getUid();
        log.info("service层打印uid:{}",uid);
        PageHelper.startPage(pageNum,10);
        List<GetUserArticlePO> userArticleS = articleMapper.getUserArticle(uid);
//        PageInfo<GetUserArticlePO> pageInfo=new PageInfo<>(userArticleS);
//        PageData<GetUserArticlePO> pageData = PageInfoToPageDataConverter.convert(pageInfo);
//        List<GetUserArticlePO> list = pageData.getList();
        log.info("ArticleService打印查询出的ArticleData:{}",userArticleS);
        List<String> articleS=new ArrayList<>();
        for (GetUserArticlePO getUserArticlePO:userArticleS) {
            String location = getUserArticlePO.getLocation();
            log.info("service层打印location:{}",location);
            String article = getArticleContent(location);
            articleS.add(article);
        }
        return JsonResult.ok(articleS);

//        log.info("service层打印pageData:{}",pageData);
//       return JsonResult.ok(pageData);

    }

    /*
    param file: 富文本编辑器生成的html文件
     */
    public JsonResult postArticleByEditor(AddArticleDTO addArticleDTO){
        String title =addArticleDTO.getTitle();
        String file = addArticleDTO.getData();

        Authentication authentication=SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        long uid = ((MyUserDetails) principal).getUid();



        FileUploadUtils fileUploadUtils=new FileUploadUtils();
        String fileName = FileUploadUtils.makeFileName(uid);
        StringBuffer stringBuffer=new StringBuffer(BASE_PATH);
        stringBuffer.append("/"+fileName+".html");
        String uploadPath = stringBuffer.toString();
        log.info("fileUploadUtils打印文件完整路径：{}",uploadPath);

        //向mysql数据库里添加文章信息
        AddArticlePO addArticlePO=new AddArticlePO();
        addArticlePO.setUid(uid);
        addArticlePO.setTitle(title);
        addArticlePO.setCreateTime(LocalDateTime.now());
        addArticlePO.setLocation(uploadPath);
        addArticlePO.setArticleId(idGenerator.nextId());
        if (file.length()>=100){
            String substring = file.substring(100);
            addArticlePO.setSynopsis(substring);
        }else{
            addArticlePO.setSynopsis(file);
        }
        int dbResultCode = articleMapper.addArticle(addArticlePO);

        //对服务器写入文章
//        int dbResultCode = addFileInfo2DB(uid, uploadPath);

        int uploadResult = fileUploadUtils.editorUpload(file,uploadPath, uid);
        if (uploadResult==0){

            if (dbResultCode==1){
                return JsonResult.ok();
            }else {
                return new JsonResult(ResultEnum.FILE_UPLOAD_FAILED);
            }

        }if (uploadResult==1){
            return new JsonResult(ResultEnum.FILE_NOT_ALLOWED_EMPTY);
        } if (uploadResult==2){
            return new JsonResult(ResultEnum.FILE_UPLOAD_FAILED);
        }
        else {
            return JsonResult.ok();
        }
    }

    /*
    从es里搜索文章
     */
    public JsonResult searchArticleByKeyword(String keyword){
        List<ArticleSearchPO> articleSearchPOS = articleSearchRepositoryImpl.searchArticleByKeyword(keyword);
        List<GetArticleDTO> getArticleDTOS=new ArrayList<>();
        for (ArticleSearchPO articleSearchPO:articleSearchPOS){
            String location = articleSearchPO.getLocation();
            String articleContent = getArticleContent(location);
            GetArticleDTO getArticleDTO = new GetArticleDTO();
            getArticleDTO.setData(articleContent);
            getArticleDTO.setUid(articleSearchPO.getUid());
            getArticleDTO.setArticleId(articleSearchPO.getArticleId());
            getArticleDTO.setCreateTime(articleSearchPO.getCreateTime());
            getArticleDTO.setSynopsis(articleSearchPO.getSynopsis());
            getArticleDTOS.add(getArticleDTO);
        }
        return JsonResult.ok(getArticleDTOS);
    }
    public int addFileInfo2DB(long uid,String location){
        long file_id = idGenerator.nextId();
        AddArticlePO addArticlePO=new AddArticlePO();
        addArticlePO.setUid(uid);
        addArticlePO.setLocation(location);
        addArticlePO.setArticleId(file_id);
        addArticlePO.setCreateTime(LocalDateTime.now());
        return articleMapper.addArticle(addArticlePO);
    }

    public AddArticlePO addArticleDTO2PO(AddArticleDTO addArticleDTO) {
        AddArticlePO addArticlePO = new AddArticlePO();
        BeanUtils.copyProperties(addArticleDTO, addArticlePO);
        LocalDateTime localDateTime=LocalDateTime.now();
        addArticlePO.setCreateTime(localDateTime);
        return  addArticlePO;
    }

}
